﻿<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3c.org/TR/1999/REC-html401-19991224/loose.dtd">
<!-- saved from url=(0054)http://msdn.microsoft.com/zh-cn/magazine/cc163328.aspx -->
<HTML style="OVERFLOW: auto" xmlns="http://www.w3.org/1999/xhtml"><HEAD 
id=ctl00_Head><TITLE>WPF 线程: 使用调度程序构建反应速度更快的应用程序</TITLE>
<META http-equiv=Content-Type content="text/html; charset=utf-8"><LINK 
id=ctl00_HeaderLink2 
href="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/Msdn10-bn20091211.css" type=text/css 
rel=stylesheet><LINK id=ctl00_HeaderLink3 
href="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/Magazine2-bn20091211.css" type=text/css 
rel=stylesheet><LINK title="MSDN Magazine - Current Issue" 
href="/magazine/rss/default.aspx?z=z&amp;iss=1" type=application/rss+xml 
rel=alternate><LINK title="MSDN Magazine - Complete" 
href="/magazine/rss/default.aspx?z=z&amp;all=1" type=application/rss+xml 
rel=alternate><LINK title="MSDN Magazine Blog" 
href="http://blogs.msdn.com/msdnmagazine/rss.xml" type=application/rss+xml 
rel=alternate><LINK 
href="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/Msdn10.ie6-bn20091211.css" type=text/css 
rel=stylesheet>
<META 
content=http://msdn.microsoft.com/zh-cn/magazine(d=default)/cc163328(l=zh-cn,v=MSDN.10).aspx 
name=NormalizedUrl>
<META 
content=http://msdn.microsoft.com/zh-cn/magazine(d=default)/cc163328(l=zh-cn,v=MSDN.10).aspx 
name=VotingContextUrl>
<META content=NOINDEX,NOFOLLOW name=ROBOTS>
<META content="1AE42B56-3:20:35 AM" name=MN>
<META content=zh-cn name=ms.locale>
<META content=cc163328 name=Search.ShortId><!-- Looking for metadata? Use the robot view instead http://currentsite/currenturl(robot).aspx --><LINK 
href="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/CAEFK9AN.css" type=text/css 
rel=stylesheet></LINK><LINK media=print 
href="/zh-cn/magazine/cc163328(printer).aspx" rel=alternate>
<META content="MSHTML 6.00.2900.5897" name=GENERATOR></HEAD>
<BODY class=MsdnPageBody id=ctl00_MTPS_Body dir=ltr>
<FORM id=aspnetForm name=aspnetForm action=cc163328.aspx method=post>
<DIV><INPUT id=__EVENTTARGET type=hidden name=__EVENTTARGET> <INPUT 
id=__EVENTARGUMENT type=hidden name=__EVENTARGUMENT> <INPUT id=__VIEWSTATE 
type=hidden 
value=/wEPDwUBMGQYAQUeX19Db250cm9sc1JlcXVpcmVQb3N0QmFja0tleV9fFgEFImN0bDAwJE1hc3RoZWFkJFNlYXJjaCRTZWFyY2hCdXR0b247+/mlIP/yyTlP3K/nXfG8CBYmcA== 
name=__VIEWSTATE> </DIV>
<SCRIPT type=text/javascript>
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
    theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
    if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
        theForm.__EVENTTARGET.value = eventTarget;
        theForm.__EVENTARGUMENT.value = eventArgument;
        theForm.submit();
    }
}
//]]>
</SCRIPT>

<SCRIPT src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/WebResource.axd" 
type=text/javascript></SCRIPT>

<SCRIPT type=text/javascript>
//<![CDATA[
var CurUserId="AxUFAAAAAAC3CAAAyIkPb6xN3OIVR2+t760eXA!!";var ClientURL="http%3a%2f%2fmsdn.microsoft.com%2fzh-cn%2fmagazine(d%3ddefault)%2fcc163328(l%3dzh-cn%2cv%3dMSDN.10).aspx";var maxRating=5;var RatingObjId="ctl00_tb1_Flyout_Rating1";var tbCommentsId="ctl00_tb1_Flyout_tbComments";var PageId="cc163328";var pageTag="contentRatingcc163328MSDN.10zh-cn";var sendBtnId="ctl00_tb1_Flyout_btnSend";var curRating="2";var contentRated=false;var RatingTooltipText="请单击星形符号并提供反馈";var RatedTooltipText="您已经为此内容评级。感谢您的反馈。";var userIPAddress="124.72.11.73";var MtpsPageDirection="ltr";var RatingFlyoutID="ctl00_tb1_Flyout";var Rating_Device="default";//]]>
</SCRIPT>

<SCRIPT src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/jquery-1.2.6-bn20091211.js" 
type=text/javascript></SCRIPT>

<SCRIPT src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/Silverlight-bn20091211.js" 
type=text/javascript></SCRIPT>

<SCRIPT type=text/javascript>
//<![CDATA[
var wt_nvr_ru = "WT_NVR_RU";var wt_fpcdom = ".microsoft.com";var wt_domlist = "msdn.microsoft.com";var wt_pathlist = "";var wt_paramlist = "DCSext.mtps_devcenter";var wt_siteid = "MSDN";var gDomain="m.webtrends.com";
var gDcsId="dcsmgru7m99k7mqmgrhudo0k8_8c6m";
var gFpc="WT_FPC";
/*<![CDATA[*/
if(document.cookie.indexOf(gFpc+"=")==-1){document.write("<scr"+"ipt type='text/javascript' src='"+"http"+(window.location.protocol.indexOf('https:')==0?'s':'')+"://"+gDomain+"/"+gDcsId+"/wtid.js"+"'><\/scr"+"ipt>");}
/*]]>*/
var detectedLocale = 'zh-cn';
var wtsp="_msdnmag_";
var gTrackEvents = 1;
var omni_guid='49b495c5-f6e3-4969-9ce9-d79cbe2477dd';//]]>
</SCRIPT>

<SCRIPT language=JavaScript 
src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/omni_rsid_msdn-bn20091211.js"></SCRIPT>
<NOSCRIPT><A title="Web Analytics" href="http://www.omniture.com/"><IMG height=1 
alt="" src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/0.gif" width=1 
border=0></A></NOSCRIPT>
<SCRIPT src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/compositejscript2.js" 
type=text/javascript></SCRIPT>
 
<DIV><INPUT id=__PREVIOUSPAGE type=hidden 
value=YD34U5UvwXkNH_SIWZEKlZQqLZnuOWWgYh9aZKoAaa01 name=__PREVIOUSPAGE> </DIV>
<SCRIPT type=text/javascript>
//<![CDATA[
Sys.WebForms.PageRequestManager._initialize('ctl00$ScriptManager1', document.getElementById('aspnetForm'));
Sys.WebForms.PageRequestManager.getInstance()._updateControls([], [], [], 90);
//]]>
</SCRIPT>

<DIV id=Msdn10Background>
<DIV class=JelloSizer id=ctl00_JelloSizer>
<DIV id=JelloExpander>
<DIV class=JelloWrapper id=ctl00_JelloWrapper>
<DIV class=Clear></DIV>
<DIV class=Masthead>
<DIV class=BrandLogo id=ctl00_Masthead_brandLogo><A id=ctl00_Masthead_brandlink 
title="MSDN Magazine" 
href="http://msdn.microsoft.com/zh-cn/magazine/default.aspx"><IMG 
style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" 
src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/logo_msdn_magazine.gif"></A> </DIV>
<DIV class=Search>
<DIV class=SearchBox id=ctl00_Masthead_Search_SearchBox><INPUT 
class=TextBoxSearch id=ctl00_Masthead_Search_SearchTextBox title="搜索 MSDN" 
name=ctl00$Masthead$Search$SearchTextBox> <INPUT class=SearchButton 
id=ctl00_Masthead_Search_SearchButton title=单击此处开始搜索 
style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" 
type=image alt=单击此处开始搜索 src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif" 
name=ctl00$Masthead$Search$SearchButton> <SPAN class=Bing></SPAN>
<SCRIPT id=mscom.srch.searchBox 
src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/SearchBox.jss" defer 
type=text/javascript></SCRIPT>
</DIV></DIV>
<DIV class=GlobalBar>
<DIV class=PassportScarab id=ctl00_Masthead_passportScarab><A id=idPPScarab 
onclick="MtpsLoginStatus.OverlayImagePath = &quot;http://i.msdn.microsoft.com:80/Platform/Controls/StoMtpsLoginStatus/resources/veil.gif&quot;; return MtpsLoginStatus.DoPassportSignIn('http://login.live.com/login.srf?wa=wsignin1.0&amp;rpsnv=11&amp;ct=1261308035&amp;rver=6.0.5276.0&amp;wp=MCLBI&amp;wlcxt=msdn%24msdn%24msdn&amp;wreply=http:%2F%2Fmsdn.microsoft.com%2FPlatform%2FControls%2FStoMtpsLoginStatus%2FPassport%2Fppsignin.htm&amp;lc=2052&amp;id=254354');" 
href="http://login.live.com/login.srf?wa=wsignin1.0&amp;rpsnv=11&amp;ct=1261308035&amp;rver=6.0.5276.0&amp;wp=MCLBI&amp;wlcxt=msdn%24msdn%24msdn&amp;wreply=http:%2F%2Fmsdn.microsoft.com%2Fzh-cn%2Fmagazine%2Fcc163328.aspx&amp;lc=2052&amp;id=254354"><SPAN 
class=MTPS_GlobalToolbarLinks_msdn id=idPPScarabSIT>登录</SPAN></A> 
<DIV id=idPPMWOverlay style="DISPLAY: none"></DIV></DIV>
<DIV class=LocaleFlyout>
<DIV id=MainDiv onmouseover=FlyoutPopupShow() onmouseout=FlyoutPopupHide()>
<DIV id=FlyoutTop><A class=LocaleManagementFlyoutStaticLink 
id=ctl00_Masthead_LocaleManagement_linkCountryLanguage 
style="DISPLAY: inline-block; WIDTH: 150px">中国 - 简体中文&nbsp;</A> <IMG 
class=LocaleManagementFlyoutPopArrow id=img_Arrow 
src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif"> </DIV>
<DIV class=LocaleManagementFlyoutPopup id=FlyoutPopup>
<TABLE width=150 border=0>
  <TBODY>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Arg 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Arg','')">Argentina 
      (Español)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Bra 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Bra','')">Brasil 
      (Português)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_CanE 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_CanE','')">Canada 
      (English)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_CanF 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_CanF','')">Canada 
      (Français)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Chi 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Chi','')">中国 
      (简体中文)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Col 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Col','')">Colombia 
      (Español)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Deu 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Deu','')">Deutschland 
      (Deutsch)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Esp 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Esp','')">España 
      (Español)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Fra 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Fra','')">France 
      (Français)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Ind 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Ind','')">India 
      (English)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Ita 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Ita','')">Italia 
      (Italiano)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Jpa 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Jpa','')">日本 
      (日本語)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Kor 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Kor','')">한국 
      (한국어)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Mex 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Mex','')">México 
      (Español)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Per 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Per','')">Perú 
      (Español)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Рос 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Рос','')">Россия 
      (Pусский)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_Tai 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_Tai','')">台灣 
      (繁體中文)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_UK 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_UK','')">United 
      Kingdom (English)</A></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_US 
      href="javascript:__doPostBack('ctl00$Masthead$LocaleManagement$lkbtn_US','')">United 
      States (English)</A></TD></TR>
  <TR>
    <TD class=LocaleManagementFlyoutPopupHr></TD></TR>
  <TR>
    <TD><A id=ctl00_Masthead_LocaleManagement_lkbtn_More 
      href='javascript:WebForm_DoPostBackWithOptions(new%20WebForm_PostBackOptions("ctl00$Masthead$LocaleManagement$lkbtn_More",%20"",%20false,%20"",%20"/zh-cn/ms376822.aspx",%20false,%20true))'>更多 
      </A></TD></TR></TBODY></TABLE></DIV></DIV></DIV>
<DIV class=Clear></DIV>
<DIV class=UserName id=ctl00_Masthead_ProfileLink_UserName></DIV></DIV>
<DIV class=Clear></DIV>
<DIV class=NetworkLogo id=ctl00_Masthead_networkTagLineArea><A 
id=ctl00_Masthead_networkLink 
href="http://msdn.microsoft.com/zh-cn/default.aspx"><IMG 
style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" 
src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/logo_msdn.gif"></A> </DIV>
<DIV class=leftcap></DIV>
<DIV class=internav>
<DIV id=ctl00_Masthead_tabs_manTabsHolder><A class=active 
id=ctl00_Masthead_tabs_ctl07 title=Home 
onclick="javascript:Track('|TabStrip Link|ctl00_Masthead_tabs_ctl06|ctl00_Masthead_tabs_ctl07',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/default.aspx">Home</A><A 
id=ctl00_Masthead_tabs_ctl09 title=Topics 
onclick="javascript:Track('|TabStrip Link|ctl00_Masthead_tabs_ctl08|ctl00_Masthead_tabs_ctl09',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/ee532082.aspx">Topics</A><A 
id=ctl00_Masthead_tabs_ctl11 title=Columns 
onclick="javascript:Track('|TabStrip Link|ctl00_Masthead_tabs_ctl10|ctl00_Masthead_tabs_ctl11',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/ee532401.aspx">Columns</A><A 
id=ctl00_Masthead_tabs_ctl13 title=Downloads 
onclick="javascript:Track('|TabStrip Link|ctl00_Masthead_tabs_ctl12|ctl00_Masthead_tabs_ctl13',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/cc135867.aspx">Downloads</A><A 
id=ctl00_Masthead_tabs_ctl15 title=Subscribe 
onclick="javascript:Track('|TabStrip Link|ctl00_Masthead_tabs_ctl14|ctl00_Masthead_tabs_ctl15',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/ee358702.aspx">Subscribe</A><A 
id=ctl00_Masthead_tabs_ctl17 title=RSS 
onclick="javascript:Track('|TabStrip Link|ctl00_Masthead_tabs_ctl16|ctl00_Masthead_tabs_ctl17',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/cc194384.aspx">RSS</A></DIV></DIV>
<DIV class=rightcap></DIV>
<DIV class=Clear></DIV>
<DIV class=LocalNavigation id=ctl00_Masthead_tabs_LocalNavigation>
<DIV class=HeaderTabs id=ctl00_Masthead_tabs_InThisSection>
<DIV class=TabOff><A id=ctl00_Masthead_tabs_ctl01 title="Current Issue" 
onclick="javascript:Track('|TabStrip Link|ctl00_Masthead_tabs_ctl00|ctl00_Masthead_tabs_ctl01',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/default.aspx">Current 
Issue</A></DIV>
<DIV class=TabOn><A id=ctl00_Masthead_tabs_ctl03 title="All Issues" 
onclick="javascript:Track('|TabStrip Link|ctl00_Masthead_tabs_ctl02|ctl00_Masthead_tabs_ctl03',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/ee310108.aspx">All 
Issues</A></DIV>
<DIV class=TabOff><A id=ctl00_Masthead_tabs_ctl05 title="HTML Help Files" 
onclick="javascript:Track('|TabStrip Link|ctl00_Masthead_tabs_ctl04|ctl00_Masthead_tabs_ctl05',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/ee412244.aspx">HTML Help 
Files</A></DIV></DIV></DIV></DIV>
<DIV class=Clear></DIV>
<DIV class=topleftcorner></DIV>
<DIV class=toprightcorner></DIV>
<DIV class=alley>
<DIV class=wrapper>
<DIV class=inner>
<DIV class=Clear></DIV>
<DIV class=EyebrowContainer id=ctl00_EyebrowMenu_EyebrowContainer><A 
class=EyebrowLink id=ctl00_EyebrowMenu_ctl00 title="MSDN Magazine" 
onclick="javascript:Track('|Eyebrow|ctl00_EyebrowMenu_EyebrowContainer|ctl00_EyebrowMenu_ctl00',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/ee348005.aspx">MSDN 
Magazine</A><SPAN>&nbsp;&gt;&nbsp;</SPAN><A class=EyebrowLink 
id=ctl00_EyebrowMenu_ctl01 title=Home 
onclick="javascript:Track('|Eyebrow|ctl00_EyebrowMenu_EyebrowContainer|ctl00_EyebrowMenu_ctl01',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/dd767791.aspx">Home</A><SPAN>&nbsp;&gt;&nbsp;</SPAN><A 
class=EyebrowLink id=ctl00_EyebrowMenu_ctl02 title="All Issues" 
onclick="javascript:Track('|Eyebrow|ctl00_EyebrowMenu_EyebrowContainer|ctl00_EyebrowMenu_ctl02',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/ee310108.aspx">All 
Issues</A><SPAN>&nbsp;&gt;&nbsp;</SPAN><A class=EyebrowLink 
id=ctl00_EyebrowMenu_ctl03 title=2007 
onclick="javascript:Track('|Eyebrow|ctl00_EyebrowMenu_EyebrowContainer|ctl00_EyebrowMenu_ctl03',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/cc135849.aspx">2007</A><SPAN>&nbsp;&gt;&nbsp;</SPAN><A 
class=EyebrowLink id=ctl00_EyebrowMenu_ctl04 title=十月 
onclick="javascript:Track('|Eyebrow|ctl00_EyebrowMenu_EyebrowContainer|ctl00_EyebrowMenu_ctl04',this);" 
href="http://msdn.microsoft.com/zh-cn/magazine/cc135412.aspx">十月</A><SPAN>&nbsp;&gt;&nbsp;</SPAN><SPAN 
class=EyebrowElement>&nbsp;WPF 线程: 使用调度程序构建反应速度更快的应用程序</SPAN></DIV>
<DIV class=Clear></DIV>
<TABLE style="TABLE-LAYOUT: fixed; WIDTH: 100%" cellSpacing=0 cellPadding=0 
width="100%" border=0>
  <TBODY>
  <TR>
    <TD style="VERTICAL-ALIGN: top; WIDTH: auto" vAlign=top>
      <DIV id=MainContent style="WIDTH: 100%">
      <DIV class=topic>
      <DIV>
      <DIV class=FeatureSmallHead>WPF 线程</DIV>
      <DIV class=FeatureHeadline>使用调度程序构建反应速度更快的应用程序</DIV>
      <DIV class=FeatureByLine>Shawn Wildermuth</DIV>
      <DIV></DIV><BR>
      <TABLE>
        <TBODY>
        <TR vAlign=top>
          <TD><SPAN class=CodeDownloadText>本文讨论: </SPAN>
            <UL>
              <LI class=ListingBullet>在 WPF 中执行线程 
              <LI class=ListingBullet>使用调度程序 
              <LI class=ListingBullet>非 UI 线程处理 
              <LI class=ListingBullet>使用计时器 </LI></UL></TD>
          <TD><SPAN class=CodeDownloadText>本文使用了以下技术: </SPAN><BR>.NET 
            Framework 3.0, WIndows Presentation 
      Foundation<BR></TD></TR></TBODY></TABLE>
      <DIV class=ContentSeparator></DIV><SPAN class=CodeDownloadText>
      <DIV class=MTPS_CollapsibleRegion>
      <DIV class=CollapseRegionLink><!-- ApplyClick with current id --><IMG 
      class=LibC_o 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif"> &nbsp;目录 </DIV>
      <DIV class=MTPS_CollapsibleSection style="DISPLAY: block"><A 
      href="http://msdn.microsoft.com/zh-cn/magazine/cc163328.aspx#S1">线程模型</A> 
      <BR><A 
      href="http://msdn.microsoft.com/zh-cn/magazine/cc163328.aspx#S2">DispatcherObject</A> 
      <BR><A 
      href="http://msdn.microsoft.com/zh-cn/magazine/cc163328.aspx#S3">使用调度程序</A> 
      <BR><A 
      href="http://msdn.microsoft.com/zh-cn/magazine/cc163328.aspx#S4">BackgroundWorker</A> 
      <BR><A 
      href="http://msdn.microsoft.com/zh-cn/magazine/cc163328.aspx#S5">DispatcherTimer</A> 
      <BR></DIV></DIV></SPAN>
      <DIV 
      class=ArticleNormalPara>如果您在创建一个直观、自然甚至精美的界面上花费了数月时间，但结果是用户不得不在他们的组合办公桌上敲打着手指等待程序响应，这会让人觉得丢脸。由于长时间运行的进程导致应用程序的屏幕停滞不动，看到这样的情况是一件痛苦的事情。然而，创建响应迅速的应用程序需要进行认真的规划，这通常需要使长时间运行的进程在其他线程中工作，以便释放出 
      UI 线程，使其随时跟上用户的进度。</DIV>
      <DIV class=ArticleNormalPara>我第一次真正体验响应速度可追溯到 Visual C++<SPAN 
      class=superscript>®</SPAN> 与 MFC 
      以及我曾经编写的第一个网格。当时，我正在帮助编写一个药学应用程序，该程序必须能够将每种药物显示在复杂的处方中。问题是有 30,000 
      种药物，因此我们决定先在 UI 线程中填充第一个满屏药物（时间大约为 50 
      毫秒），给人一种反应迅速的印象，然后使用后台线程完成填充不可见的药物（时间大约为 10 
      秒）。项目运行良好，而且我学到了非常宝贵的经验，那就是用户感知可以比现实更重要。</DIV>
      <DIV class=ArticleNormalPara>在创建具有吸引力的用户界面方面，Windows<SPAN 
      class=superscript>®</SPAN> Presentation Foundation (WPF) 
      是一项出色的技术，但这并不意味着您就不需要考虑应用程序的响应性。不管相关的长时间运行进程的类型为何（不管是从数据库获取大量结果，进行异步 Web 
      服务调用，还是任何数量的其他潜在密集型操作），简单的事实就是，响应更快的应用程序是让用户更满意的长期保证。但是，开始在 WPF 
      应用程序中使用异步编程模型之前，了解 WPF 
      线程模型非常重要。在本文中，我不但将会向您介绍此线程模型，还会向您展示基于调度程序的对象的工作原理，以及解释如何使用 
      BackgroundWorker 以便创建具有吸引力和响应性的用户界面。</DIV><BR>
      <DIV class=ArticleTypeTitle id=S1>线程模型</DIV>
      <DIV class=ArticleNormalPara>所有 WPF 
      应用程序启动时都会加载两个重要的线程：一个用于呈现用户界面，另一个用于管理用户界面。呈现线程是一个在后台运行的隐藏线程，因此您通常面对的唯一线程就是 
      UI 线程。WPF 要求将其大多数对象与 UI 线程进行关联。这称之为线程关联，意味着要使用一个 WPF 
      对象，只能在创建它的线程上使用。在其他线程上使用它会导致引发运行时异常。注意，WPF 线程模型可与基于 Win32<SPAN 
      class=superscript>®</SPAN> 的 API 进行顺畅的交互。这意味着 WPF 可以承载或承载于任何基于 HWND 的 
      API（Windows Forms、Visual Basic<SPAN class=superscript>®</SPAN>、MFC，甚至是 
      Win32）。</DIV>
      <DIV class=ArticleNormalPara>线程关联由 Dispatcher 类处理，该类即是用于 WPF 
      应用程序的、按优先级排列的消息循环。通常，WPF 项目有单个 Dispatcher 对象（因此有单个 UI 
      线程），所有用户界面工作均以其为通道。</DIV>
      <DIV class=ArticleNormalPara>与典型的消息循环不同，发送到 WPF 的每个工作项目都以特定的优先级通过 
      Dispatcher 
      进行发送。这就能够按优先级对项目排序，并延迟某种类型的工作，直到系统有时间来处理它们。（例如，有些工作项目可被延迟到系统或应用程序处于空闲状态时。） 
      支持项目优先顺序使 WPF 能够让某种类型的工作拥有更多的权限，因此在线程上拥有比其他工作更多的时间。</DIV>
      <DIV 
      class=ArticleNormalPara>在本文的后面，我将会阐明，呈现引擎在更新用户界面方面比输入系统具备更高的优先级。这意味着不管用户是否正在使用鼠标、键盘或墨水打印系统，动画都将会继续更新用户界面。这可以使用户界面看起来响应更快。例如，让我们假定您正在编写一个音乐播放应用程序（类似于 
      Windows Media<SPAN class=superscript>®</SPAN> 
      Player）。不管用户是否正在使用界面，您最有可能希望显示有关音乐播放的信息（包括进度条和其他信息）。对用户来说，这可以使界面看起来对他们最感兴趣的事情（在此例中为听音乐）响应更快。</DIV>
      <DIV class=ArticleNormalPara>除了使用 Dispatcher 的消息循环将工作项目引导至用户界面线程之外，每个 WPF 
      对象也可感知对其负责的 Dispatcher（以及它由此所依赖的 UI 线程）。这意味着任何从第二个线程更新 WPF 对象的尝试均会失败。这就是 
      DispatcherObject 类的职责。</DIV><BR>
      <DIV class=ArticleTypeTitle id=S2>DispatcherObject</DIV>
      <DIV class=ArticleNormalPara>在 WPF 的类层次结构中，大部分都集中派生于 DispatcherObject 
      类（通过其他类）。如<STRONG>图 1</STRONG> 所示，您可以看到 DispatcherObject 虚拟类正好位于 Object 
      下方和大多数 WPF 类的层次结构之间。</DIV>
      <DIV class=ArticleImageSpacer><IMG alt="" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/cc163328.fig01(zh-cn).gif"> 
      <DIV class=ArticleImageCaptionText>图 1<STRONG>&nbsp;Dispatcher&shy;Object 
      派生&nbsp;</STRONG></DIV></DIV>
      <DIV class=ArticleNormalPara>DispatcherObject 类有两个主要职责：提供对对象所关联的当前 
      Dispatcher 的访问权限，以及提供方法以检查 (CheckAccess) 和验证 (VerifyAccess) 
      某个线程是否有权访问对象（派生于 DispatcherObject）。CheckAccess 与 VerifyAccess 的区别在于 
      CheckAccess 返回一个布尔值，表示当前线程是否可以使用对象，而 VerifyAccess 
      则在线程无权访问对象的情况下引发异常。通过提供这些基本的功能，所有 WPF 对象都支持对是否可在特定线程（特别是 UI 
      线程）上使用它们加以确定。如果您正在编写您自己的 WPF 对象（诸如控件），那么您使用的所有方法都应在执行任何工作之前调用 
      VerifyAccess。这可确保您的对象仅在 UI 线程上使用，如<STRONG>图 2</STRONG> 所示。</DIV><SPAN>
      <DIV class=MTPS_CollapsibleRegion>
      <DIV class=CollapseRegionLink><!-- ApplyClick with current id --><IMG 
      class=LibC_o 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif"> 
      &nbsp;Figure&nbsp;2&nbsp;使用 VerifyAccess 与 CheckAccess </DIV>
      <DIV class=MTPS_CollapsibleSection style="DISPLAY: block"><SPAN 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl18_ctl00_ctl00 
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">
      <DIV class=libCScode 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl18_ctl00_ctl00_>
      <DIV class=CodeSnippetTitleBar>
      <DIV class=CodeDisplayLanguage></DIV>
      <DIV class=CopyCodeButton><A class=copyCode title=复制代码 
      href="javascript:CopyCode('ctl00_MTContentSelector1_mainContentContainer_ctl18_ctl00_ctl00_code');">
      <DIV class=LibC_copy_off 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; WIDTH: auto; HEIGHT: 9px; BORDER-RIGHT-WIDTH: 0px" 
      align=center></DIV>复制代码 </A></DIV></DIV>
      <DIV dir=ltr style="BACKGROUND-COLOR: #ddd"><PRE class=libCScode id=ctl00_MTContentSelector1_mainContentContainer_ctl18_ctl00_ctl00_code style="WORD-BREAK: break-all; WORD-WRAP: break-word" space="preserve">public class MyWpfObject : DispatcherObject
{
    public void DoSomething()       
    {
        VerifyAccess();

        // Do some work
    }

    public void DoSomethingElse()
    {
        if (CheckAccess())
        {
            // Something, only if called 
            // on the right thread
        }
    }
}

</PRE></DIV></DIV></SPAN></DIV></DIV></SPAN>
      <DIV class=ArticleNormalPara>为此，在调用 Control、Window、Panel 之类的任何 
      DispatcherObject 派生对象时，应注意要处在 UI 线程上。如果您从非 UI 线程调用 
      DispatcherObject，就会引发异常。相反，如果您正在某个非 UI 线程上工作，就需要使用 Dispatcher 来更新 
      DispatcherObjects。</DIV><BR>
      <DIV class=ArticleTypeTitle id=S3>使用调度程序</DIV>
      <DIV class=ArticleNormalPara>Dispatcher 类提供了到 WPF 中消息泵的通道，还提供了一种机制来路由供 UI 
      线程处理的工作。这对满足线程关联要求是必要的，但是对通过 Dispatcher 路由的每个工作来说，UI 线程都被阻止，因此使 Dispatcher 
      完成的工作小而快非常重要。最好将用户界面的大块工作拆分为较小的离散块，以便 Dispatcher 执行。任何不需要在 UI 
      线程上完成的工作应移到其他线程上，以便在后台进行处理。</DIV>
      <DIV class=ArticleNormalPara>通常，您将会使用 Dispatcher 类将工作项目发送到 UI 
      线程进行处理。例如，如果您想要使用 Thread 类在单独的线程上进行一些工作，那么可以创建一个 ThreadStart 
      委托，在新的线程上进行一些工作，如<STRONG>图 3</STRONG> 所示。</DIV><SPAN>
      <DIV class=MTPS_CollapsibleRegion>
      <DIV class=CollapseRegionLink><!-- ApplyClick with current id --><IMG 
      class=LibC_o 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif"> 
      &nbsp;Figure&nbsp;3&nbsp;用非 UI 线程更新 UI——错误的方法 </DIV>
      <DIV class=MTPS_CollapsibleSection style="DISPLAY: block"><SPAN 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl19_ctl00_ctl00 
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">
      <DIV class=libCScode 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl19_ctl00_ctl00_>
      <DIV class=CodeSnippetTitleBar>
      <DIV class=CodeDisplayLanguage></DIV>
      <DIV class=CopyCodeButton><A class=copyCode title=复制代码 
      href="javascript:CopyCode('ctl00_MTContentSelector1_mainContentContainer_ctl19_ctl00_ctl00_code');">
      <DIV class=LibC_copy_off 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; WIDTH: auto; HEIGHT: 9px; BORDER-RIGHT-WIDTH: 0px" 
      align=center></DIV>复制代码 </A></DIV></DIV>
      <DIV dir=ltr style="BACKGROUND-COLOR: #ddd"><PRE class=libCScode id=ctl00_MTContentSelector1_mainContentContainer_ctl19_ctl00_ctl00_code style="WORD-BREAK: break-all; WORD-WRAP: break-word" space="preserve">// The Work to perform on another thread
ThreadStart start = delegate()
{
    // ...

    // This will throw an exception 
    // (it's on the wrong thread)
    statusText.Text = "From Other Thread";
};

// Create the thread and kick it started!
new Thread(start).Start();

</PRE></DIV></DIV></SPAN></DIV></DIV></SPAN>
      <DIV class=ArticleNormalPara>此代码执行失败，原因是当前没有在 UI 线程上调用对 statusText 控件（一种 
      TextBlock）的 Text 属性的设置。当该代码尝试设置 TextBlock 上的 Text 时，TextBlock 类会在内部调用其 
      VerifyAccess 方法以确保该调用来自 UI 线程。当它确定调用是来自不同的线程时，则会引发异常。那么您如何使用 Dispatcher 在 
      UI 线程上进行调用呢？</DIV>
      <DIV class=ArticleNormalPara>Dispatcher 类提供了在 UI 线程上直接调用代码的权限。<STRONG>图 
      4</STRONG> 展示了使用 Dispatcher 的 Invoke 方法来调用名叫 SetStatus 的方法，从而更改 TextBlock 
      的 Text 属性。</DIV><SPAN>
      <DIV class=MTPS_CollapsibleRegion>
      <DIV class=CollapseRegionLink><!-- ApplyClick with current id --><IMG 
      class=LibC_o 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif"> 
      &nbsp;Figure&nbsp;4&nbsp;更新 UI </DIV>
      <DIV class=MTPS_CollapsibleSection style="DISPLAY: block"><SPAN 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl20_ctl00_ctl00 
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">
      <DIV class=libCScode 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl20_ctl00_ctl00_>
      <DIV class=CodeSnippetTitleBar>
      <DIV class=CodeDisplayLanguage></DIV>
      <DIV class=CopyCodeButton><A class=copyCode title=复制代码 
      href="javascript:CopyCode('ctl00_MTContentSelector1_mainContentContainer_ctl20_ctl00_ctl00_code');">
      <DIV class=LibC_copy_off 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; WIDTH: auto; HEIGHT: 9px; BORDER-RIGHT-WIDTH: 0px" 
      align=center></DIV>复制代码 </A></DIV></DIV>
      <DIV dir=ltr style="BACKGROUND-COLOR: #ddd"><PRE class=libCScode id=ctl00_MTContentSelector1_mainContentContainer_ctl20_ctl00_ctl00_code style="WORD-BREAK: break-all; WORD-WRAP: break-word" space="preserve">// The Work to perform on another thread
ThreadStart start = delegate()
{
  // ...

  // Sets the Text on a TextBlock Control.
  // This will work as its using the dispatcher
  Dispatcher.Invoke(DispatcherPriority.Normal, 
                    new Action&lt;string&gt;(SetStatus), 
                    "From Other Thread");
};
// Create the thread and kick it started!
new Thread(start).Start();
</PRE></DIV></DIV></SPAN></DIV></DIV></SPAN>
      <DIV class=ArticleNormalPara>该 Invoke 
      调用包含三条信息：要执行的项目的优先级、说明要执行何种工作的委托，以及任何传递给第二个参数中所述委托的参数。通过调用 Invoke，它将要在 UI 
      线程上调用的委托排入队列。使用 Invoke 方法可确保在 UI 线程上执行工作之前保持阻止。</DIV>
      <DIV class=ArticleNormalPara>作为一种异步使用 Dispatcher 的替代方法，您可以使用 Dispatcher 的 
      BeginInvoke 方法为 UI 线程异步排队工作项目。调用 BeginInvoke 方法会返回一个 DispatcherOperation 
      类的实例，其中包含有关执行工作项目的信息，包括工作项目的当前状态和执行的结果（如果工作项目已完成）。BeginInvoke 方法和 
      DispatcherOperation 类的使用如<STRONG>图 5</STRONG> 所示。</DIV><SPAN>
      <DIV class=MTPS_CollapsibleRegion>
      <DIV class=CollapseRegionLink><!-- ApplyClick with current id --><IMG 
      class=LibC_o 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif"> 
      &nbsp;Figure&nbsp;5&nbsp;异步更新 UI </DIV>
      <DIV class=MTPS_CollapsibleSection style="DISPLAY: block"><SPAN 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl21_ctl00_ctl00 
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">
      <DIV class=libCScode 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl21_ctl00_ctl00_>
      <DIV class=CodeSnippetTitleBar>
      <DIV class=CodeDisplayLanguage></DIV>
      <DIV class=CopyCodeButton><A class=copyCode title=复制代码 
      href="javascript:CopyCode('ctl00_MTContentSelector1_mainContentContainer_ctl21_ctl00_ctl00_code');">
      <DIV class=LibC_copy_off 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; WIDTH: auto; HEIGHT: 9px; BORDER-RIGHT-WIDTH: 0px" 
      align=center></DIV>复制代码 </A></DIV></DIV>
      <DIV dir=ltr style="BACKGROUND-COLOR: #ddd"><PRE class=libCScode id=ctl00_MTContentSelector1_mainContentContainer_ctl21_ctl00_ctl00_code style="WORD-BREAK: break-all; WORD-WRAP: break-word" space="preserve">// The Work to perform on another thread
ThreadStart start = delegate()
{
    // ...

    // This will work as its using the dispatcher
    DispatcherOperation op = Dispatcher.BeginInvoke(
        DispatcherPriority.Normal, 
        new Action&lt;string&gt;(SetStatus), 
        "From Other Thread (Async)");
    
    DispatcherOperationStatus status = op.Status;
    while (status != DispatcherOperationStatus.Completed)
    {
        status = op.Wait(TimeSpan.FromMilliseconds(1000));
        if (status == DispatcherOperationStatus.Aborted)
        {
            // Alert Someone
        }
    }
};

// Create the thread and kick it started!
new Thread(start).Start();

</PRE></DIV></DIV></SPAN></DIV></DIV></SPAN>
      <DIV class=ArticleNormalPara>与典型的消息泵实现不同，Dispatcher 
      是基于优先级的工作项目队列。这就能够实现更好的响应性，因为重要性更高的工作能够在重要性较低的工作之前执行。优先顺序的本质可通过 
      DispatchPriority 枚举中指定的优先级加以例证（如<STRONG>图 6</STRONG> 所示）。</DIV><SPAN>
      <DIV class=MTPS_CollapsibleRegion>
      <DIV class=CollapseRegionLink><!-- ApplyClick with current id --><IMG 
      class=LibC_o 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif"> 
      &nbsp;Figure&nbsp;6&nbsp;DispatchPriority 优先级别（按优先级次序） </DIV>
      <DIV class=MTPS_CollapsibleSection style="DISPLAY: block"><BR>
      <TABLE class=charttable>
        <TBODY>
        <TR>
          <TH>优先级</TH>
          <TH>说明</TH></TR>
        <TR>
          <TD vAlign=top>非活动</TD>
          <TD vAlign=top>工作项目已排队但未处理。 </TD></TR>
        <TR>
          <TD vAlign=top>SystemIdle</TD>
          <TD vAlign=top>仅当系统空闲时才将工作项目调度到 UI 线程。这是实际得到处理的项目的最低优先级。</TD></TR>
        <TR>
          <TD vAlign=top>ApplicationIdle</TD>
          <TD vAlign=top>仅当应用程序本身空闲时才将工作项目调度到 UI 线程。</TD></TR>
        <TR>
          <TD vAlign=top>ContextIdle</TD>
          <TD vAlign=top>仅在优先级更高的工作项目得到处理后才将工作项目调度到 UI 线程。</TD></TR>
        <TR>
          <TD vAlign=top>后台</TD>
          <TD vAlign=top>在所有布局、呈现和输入项目都得到处理后才将工作项目调度到 UI 线程。</TD></TR>
        <TR>
          <TD vAlign=top>输入</TD>
          <TD vAlign=top>以与用户输入相同的优先级将工作项目调度到 UI 线程。</TD></TR>
        <TR>
          <TD vAlign=top>已加载</TD>
          <TD vAlign=top>在所有布局和呈现都完成后才将工作项目调度到 UI 线程。 </TD></TR>
        <TR>
          <TD vAlign=top>呈现</TD>
          <TD vAlign=top>以与呈现引擎相同的优先级将工作项目调度到 UI 线程。</TD></TR>
        <TR>
          <TD vAlign=top>DataBind</TD>
          <TD vAlign=top>以与数据绑定相同的优先级将工作项目调度到 UI 线程。</TD></TR>
        <TR>
          <TD vAlign=top>正常</TD>
          <TD vAlign=top>以正常优先级将工作项目调度到 UI 线程。这是调度大多数应用程序工作项目时的优先级。</TD></TR>
        <TR>
          <TD vAlign=top>发送</TD>
          <TD vAlign=top>以最高优先级将工作项目调度到 UI 线程。 
      </TD></TR></TBODY></TABLE></DIV></DIV></SPAN>
      <DIV class=ArticleNormalPara>一般来说，对于更新 UI 外观的工作项目（如我之前使用的示例），您应始终使用 
      DispatcherPriority.Normal 
      优先级。但也有时候应该使用不同的优先级。其中尤其令人感兴趣的是三个空闲优先级（ContextIdle、ApplicationIdle 和 
      SystemIdle）。通过这些优先级可以指定仅在工作负载很低的情况下执行的工作项目。</DIV><BR>
      <DIV class=ArticleTypeTitle id=S4>BackgroundWorker</DIV>
      <DIV class=ArticleNormalPara>现在您对 Dispatcher 
      的工作原理已有所了解，那么如果得知在大多数情况下都不会使用它，您可能会感到惊讶。在 Windows Forms 2.0 中，Microsoft 
      引入了一个用于非 UI 线程处理的类来为用户界面开发人员简化开发模型。此类称为 BackgroundWorker。<STRONG>图 
      7</STRONG> 显示了 BackgroundWorker 类的典型用法。</DIV><SPAN>
      <DIV class=MTPS_CollapsibleRegion>
      <DIV class=CollapseRegionLink><!-- ApplyClick with current id --><IMG 
      class=LibC_o 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif"> 
      &nbsp;Figure&nbsp;7&nbsp;在 WPF 中使用 BackgroundWorker </DIV>
      <DIV class=MTPS_CollapsibleSection style="DISPLAY: block"><SPAN 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl23_ctl00_ctl00 
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">
      <DIV class=libCScode 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl23_ctl00_ctl00_>
      <DIV class=CodeSnippetTitleBar>
      <DIV class=CodeDisplayLanguage></DIV>
      <DIV class=CopyCodeButton><A class=copyCode title=复制代码 
      href="javascript:CopyCode('ctl00_MTContentSelector1_mainContentContainer_ctl23_ctl00_ctl00_code');">
      <DIV class=LibC_copy_off 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; WIDTH: auto; HEIGHT: 9px; BORDER-RIGHT-WIDTH: 0px" 
      align=center></DIV>复制代码 </A></DIV></DIV>
      <DIV dir=ltr style="BACKGROUND-COLOR: #ddd"><PRE class=libCScode id=ctl00_MTContentSelector1_mainContentContainer_ctl23_ctl00_ctl00_code style="WORD-BREAK: break-all; WORD-WRAP: break-word" space="preserve">BackgroundWorker _backgroundWorker = new BackgroundWorker();

...

// Set up the Background Worker Events
_backgroundWorker.DoWork += _backgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += 
    _backgroundWorker_RunWorkerCompleted;

// Run the Background Worker
_backgroundWorker.RunWorkerAsync(5000);

...

// Worker Method
void _backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    // Do something
}

// Completed Method
void _backgroundWorker_RunWorkerCompleted(
    object sender, 
    RunWorkerCompletedEventArgs e)
{
    if (e.Cancelled)
    {
        statusText.Text = "Cancelled";
    }
    else if (e.Error != null) 
    {
        statusText.Text = "Exception Thrown";
    }
    else 
    {
        statusText.Text = "Completed";
    }
}

</PRE></DIV></DIV></SPAN></DIV></DIV></SPAN>
      <DIV class=ArticleNormalPara>BackgroundWorker 组件与 WPF 的配合非常好，因为在后台它使用了 
      AsyncOperationManager 类，该类随之又使用 SynchronizationContext 类来处理同步。在 Windows 
      Forms 中，AsyncOperationManager 递交从 SynchronizationContext 类派生的 
      WindowsFormsSynchronizationContext 类。同样，在 ASP.NET 中，它与 
      SynchronizationContext 的不同派生（称为 AspNetSynchronizationContext）配合使用。这些 
      SynchronizationContext 派生的类知道如何处理方法调用的跨线程同步。</DIV>
      <DIV class=ArticleNormalPara>在 WPF 中，可用 DispatcherSynchronizationContext 
      类来扩展此模型。通过使用 BackgroundWorker，可自动应用 Dispatcher 
      来调用跨线程方法调用。好消息是，由于您可能已经熟悉了这个常见的模式，因此可以继续在新的 WPF 项目中使用 
      BackgroundWorker。</DIV><BR>
      <DIV class=ArticleTypeTitle id=S5>DispatcherTimer</DIV>
      <DIV class=SidebarContainer>
      <DIV class=SidebarHeadline>WPF 线程资源 </DIV>
      <UL>
        <LI><A 
        href="http://microsoft.com/india/virtuallabs/workflow_full.aspx">Windows 
        Presentation Foundation 虚拟实验室</A> 
        <LI><A 
        href="http://msdn2.microsoft.com/en-us/netframework/aa663321.aspx">.NET 
        Framework 开发中心的 WPF</A> 
        <LI><A href="http://msdn2.microsoft.com/ms741870">WPF 基础：线程模型，MSDN 库</A> 

        <LI><A href="http://oreilly.com/catalog/avalon">“Programming the Windows 
        Presentation Foundation”（Windows Presentation Foundation 编程），作者 Chris 
        Sells 和 Ian Griffiths (O'Reilly, 2005)</A> </LI></UL><BR></DIV>
      <DIV class=ArticleNormalPara>在 Microsoft<SPAN class=superscript>®</SPAN> 
      .NET Framework 中定期执行代码是开发中的一项常见任务，但是在 .NET 中使用计时器仍令人困惑。如果您在 .NET Framework 
      基类库 (BCL) 中查找 Timer 类，那么至少会找到 3 种 Timer 
      类：System.Threading.Timer、System.Timers.Timer 和 
      System.Windows.Forms.Timer。每种计时器均有所不同。Alex Calvo 在《MSDN 杂志》中的文章解释了何时使用这些 
      Timer 类中的每个类（请参见 <A 
      href="http://msdn.microsoft.com/msdnmag/issues/04/02/TimersinNET">msdn.microsoft.com/msdnmag/issues/04/02/TimersinNET</A>）。</DIV>
      <DIV class=ArticleNormalPara>对于 WPF 应用程序来说，有一种使用 Dispatcher（即 
      DispatcherTimer 类）的新型计时器。与其他计时器类似，DispatcherTimer 
      类支持指定滴答之间的间隔，以及在计时器事件触发时要运行的代码。在<STRONG>图 8</STRONG> 中可以看到一种相当常见的 
      DispatcherTimer 使用方法。</DIV><SPAN>
      <DIV class=MTPS_CollapsibleRegion>
      <DIV class=CollapseRegionLink><!-- ApplyClick with current id --><IMG 
      class=LibC_o 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; VERTICAL-ALIGN: middle; BORDER-RIGHT-WIDTH: 0px" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/clear.gif"> 
      &nbsp;Figure&nbsp;8&nbsp;运行中的 DispatcherTimer 类 </DIV>
      <DIV class=MTPS_CollapsibleSection style="DISPLAY: block"><SPAN 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl24_ctl00_ctl00 
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">
      <DIV class=libCScode 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl24_ctl00_ctl00_>
      <DIV class=CodeSnippetTitleBar>
      <DIV class=CodeDisplayLanguage></DIV>
      <DIV class=CopyCodeButton><A class=copyCode title=复制代码 
      href="javascript:CopyCode('ctl00_MTContentSelector1_mainContentContainer_ctl24_ctl00_ctl00_code');">
      <DIV class=LibC_copy_off 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; WIDTH: auto; HEIGHT: 9px; BORDER-RIGHT-WIDTH: 0px" 
      align=center></DIV>复制代码 </A></DIV></DIV>
      <DIV dir=ltr style="BACKGROUND-COLOR: #ddd"><PRE class=libCScode id=ctl00_MTContentSelector1_mainContentContainer_ctl24_ctl00_ctl00_code style="WORD-BREAK: break-all; WORD-WRAP: break-word" space="preserve">// Create a Timer with a Normal Priority
_timer = new DispatcherTimer();

// Set the Interval to 2 seconds
_timer.Interval = TimeSpan.FromMilliseconds(2000); 

// Set the callback to just show the time ticking away
// NOTE: We are using a control so this has to run on 
// the UI thread
_timer.Tick += new EventHandler(delegate(object s, EventArgs a) 
{ 
    statusText.Text = string.Format(
        "Timer Ticked:  {0}ms", Environment.TickCount); 
});

// Start the timer
_timer.Start();

</PRE></DIV></DIV></SPAN></DIV></DIV></SPAN>
      <DIV class=ArticleNormalPara>因为 DispatcherTimer 类与 Dispatcher 相关联，因此还可以指定 
      DispatcherPriority 以及要使用的 Dispatcher。DispatcherTimer 类使用“正常”优先级作为当前 
      Dispatcher 的默认优先级，但是您可以覆盖这些值：</DIV>
      <DIV class=ArticleNormalPara><SPAN 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl16 
      xmlns:msxsl="urn:schemas-microsoft-com:xslt">
      <DIV class=libCScode 
      id=ctl00_MTContentSelector1_mainContentContainer_ctl16_>
      <DIV class=CodeSnippetTitleBar>
      <DIV class=CodeDisplayLanguage></DIV>
      <DIV class=CopyCodeButton><A class=copyCode title=复制代码 
      href="javascript:CopyCode('ctl00_MTContentSelector1_mainContentContainer_ctl16_code');">
      <DIV class=LibC_copy_off 
      style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; WIDTH: auto; HEIGHT: 9px; BORDER-RIGHT-WIDTH: 0px" 
      align=center></DIV>复制代码 </A></DIV></DIV>
      <DIV dir=ltr style="BACKGROUND-COLOR: #ddd"><PRE class=libCScode id=ctl00_MTContentSelector1_mainContentContainer_ctl16_code style="WORD-BREAK: break-all; WORD-WRAP: break-word" space="preserve">_timer = new DispatcherTimer(
    DispatcherPriority.SystemIdle, form1.Dispatcher);
</PRE></DIV></DIV></SPAN></DIV>
      <DIV 
      class=ArticleNormalPara>规划工作进程以获得响应更快的应用程序，其中的一切努力都是非常值得的。开展一些初期研究工作可以使规划更成功。我建议您在开始之前浏览一下“WPF 
      线程参考”侧栏中提到的一些网站以及本文章，它们会为您开发响应更快的应用程序打下良好的基础。</DIV><BR>
      <DIV class=ContentSeparator></DIV>
      <DIV class=AuthorBio><STRONG>Shawn Wildermuth</STRONG>不仅是 Microsoft 
      MVP、MCSD.NET 和 MCT 的创始人，而且还是 Wildermuth Consulting Services 的创始人。此外，Shawn 
      是“Pragmatic ADO.NET”（实用 ADO.NET）(Addison-Wesley, 2002) 的作者，而且还与他人合著了四套 
      Microsoft 认证培训系列教材以及即将出版的“Prescriptive Data 
      Architectures”（规定性数据体系结构）。您可以通过其网站与他联系，网址为 <A 
      href="http://wildermuthconsulting.com/">wildermuthconsulting.com</A>。</DIV><BR></DIV></DIV></DIV>
      <DIV class=FeatureSmallHeadWithLogo>&nbsp;</DIV></TD>
    <TD style="PADDING-LEFT: 3px; VERTICAL-ALIGN: top; WIDTH: 303px" 
      vAlign=top><DIV id=RightContent>
      <DIV id=ctl00_RightSideBox>
      <DIV class=navpage>
      <DIV class=RightAdRail>
      <DIV><IFRAME id=ctl00_ctl16_iframeinclude 
      style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px" 
      marginWidth=0 marginHeight=0 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/pos=top.htm" frameBorder=0 width=305 
      scrolling=no height=260></IFRAME></DIV>
      <DIV><IFRAME id=ctl00_ctl17_iframeinclude 
      style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px" 
      marginWidth=0 marginHeight=0 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/pos=BOTTOM.htm" frameBorder=0 
      width=305 scrolling=no height=260></IFRAME></DIV></DIV>
      <DIV style="WIDTH: 100%">
      <DIV style="BACKGROUND-COLOR: #5b6871">
      <P>&nbsp;</P></DIV>
      <DIV style="FONT-SIZE: 12pt; FONT-FAMILY: Segoe; TEXT-ALIGN: left">Current 
      Issue</DIV>
      <DIV style="DISPLAY: block; TEXT-ALIGN: center">
      <P><A id=ctl00_ctl18 
      onclick="javascript:Track('ctl00_ctl15|ctl00_ctl18',this);" 
      href="http://msdn.microsoft.com/zh-cn/magazine/ee835718.aspx"><IMG 
      title="MSDN Magazine December 2009 Issue" 
      alt="MSDN Magazine December 2009 Issue" 
      src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/ee835718.Dec_cover_small(en-us,MSDN.10).png" 
      align=middle></A></P>
      <P>&nbsp;</P></DIV>
      <DIV style="TEXT-ALIGN: right">
      <P><A id=ctl00_ctl19 
      onclick="javascript:Track('ctl00_ctl15|ctl00_ctl19',this);" 
      href="http://msdn.microsoft.com/zh-cn/magazine/ee310108.aspx">Browse All 
      MSDN Magazines</A><BR></P></DIV>
      <DIV style="BACKGROUND-COLOR: #5b6871">
      <P>&nbsp;</P></DIV></DIV></DIV></DIV></DIV></TD></TR></TBODY></TABLE>
<DIV class=MsdnPage_ContentInclude id=ctl00_FooterAd align=center>
<DIV>
<DIV>
<DIV class=navpage>
<P>&nbsp;</P>
<DIV><IFRAME id=ctl00_ctl23_iframeinclude 
style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px" 
marginWidth=0 marginHeight=0 
src="G:\l论文资料\基于WPF的数独游戏的开发\百科\数独资料\WPF 线程 使用调度程序构建反应速度更快的应用程序.files\pos=TOP(1).htm" 
frameBorder=0 width=728 scrolling=no 
height=260></IFRAME></DIV></DIV></DIV></DIV></DIV></DIV></DIV></DIV>
<DIV class=Clearbottom></DIV>
<DIV class=bottomleftcorner></DIV>
<DIV class=bottomrightcorner></DIV>
<DIV id=Footer>
<DIV class=FooterLinks>
<DIV id=ctl00_Footer1_SiteLinks><A id=ctl00_Footer1_LocalFooterLink0 
title=个人信息中心 
href="http://go.microsoft.com/?linkid=8786242&amp;lcid=2052">个人信息中心</A><SPAN 
class=Pipe>|</SPAN><A id=ctl00_Footer1_LocalFooterLink1 title=法律信息 
href="http://www.microsoft.com/legal/">法律信息</A><SPAN class=Pipe>|</SPAN><A 
id=ctl00_Footer1_LocalFooterLink2 title="MSDN Flash 中心" 
href="http://www.microsoft.com/china/msdn/newsletter/default.aspx">MSDN Flash 
中心</A><SPAN class=Pipe>|</SPAN><A id=ctl00_Footer1_LocalFooterLink3 title=联系我们 
href="mailto:msdnonln@microsoft.com">联系我们</A> </DIV><SPAN class=FooterCopyright 
id=ctl00_Footer1_Copyright title="© 2009  Microsoft Corporation 版权所有。 ">© 2009 
Microsoft Corporation 版权所有。 </SPAN><A id=ctl00_Footer1_Terms title=保留所有权利 
href="http://msdn.microsoft.com/zh-cn/cc300389.aspx">保留所有权利</A> <SPAN 
class=Pipe>|</SPAN> <A id=ctl00_Footer1_Trademarks title=商标 
href="http://www.microsoft.com/library/toolbar/3.0/trademarks/zh-cn.mspx">商标</A> 
<SPAN class=Pipe>|</SPAN> <A id=ctl00_Footer1_PrivacyStatement title=隐私权声明 
href="http://www.microsoft.com/info/cn/privacy.mspx">隐私权声明</A> <A 
id=ctl00_Footer1_Feedback target=_blank 
rel=sitefeedback></A></DIV></DIV></DIV></DIV></DIV></DIV>
<DIV style="DISPLAY: none"><IMG height=0 alt="Page view tracker" hspace=0 
src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/trans_pixel.gif" width=0 border=0></DIV>
<SCRIPT src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/webtrendsscript-bn20091211.js" 
type=text/javascript></SCRIPT>
<NOSCRIPT>
<DIV><IMG id=Img1 height=1 alt=DCSIMG 
src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/njs.gif" width=1></DIV></NOSCRIPT>
<SCRIPT src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/CA4LIP7O.js" 
type=text/javascript></SCRIPT>

<SCRIPT type=text/javascript>
//<![CDATA[
Sys.Application.initialize();
//]]>
</SCRIPT>
</FORM>
<SCRIPT language=javascript src="WPF 线程 使用调度程序构建反应速度更快的应用程序.files/broker.js" 
type=text/javascript></SCRIPT>
</BODY></HTML>
